<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="1038.32">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #376c2a}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica; min-height: 22.0px}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #606060}
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #cd1713}
p.p10 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco; color: #737373}
p.p11 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco; color: #cd1713}
p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #000000; min-height: 12.0px}
p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #ad140d}
p.p14 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco; color: #ad140d}
p.p15 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 9.0px Monaco}
span.s1 {font: 12.0px Helvetica; color: #000000}
span.s2 {color: #001bb9}
span.s3 {color: #000000}
span.s4 {color: #102ac3}
span.s5 {color: #606060}
span.s6 {color: #2c7014}
span.s7 {color: #ad140d}
span.Apple-tab-span {white-space:pre}
</style>
</head>
<body>
<p class="p1">//Copyright (C) 2006<span class="Apple-converted-space">  </span>Nick Collins distributed under the terms of the GNU General Public License</p>
<p class="p2"><br></p>
<p class="p3"><b>Qitch<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>constant Q transform pitch follower</b></p>
<p class="p4"><br></p>
<p class="p5"><b>#freq, hasFreq = Qitch.kr(in, databufnum,ampThreshold, algoflag, ampbufnum, minfreq, maxfreq)</b></p>
<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
<p class="p5">This alternative pitch follower works in the frequency domain rather than Pitch's time domain correlation. Tradeoffs are made between latency and frequency resolution. It is meant to provide a relatively stable resultant tracked pitch based on a harmonic template. <span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5">You must load one of the auxilliary data files into a Buffer and pass the bufnum to the routine. These files take the form:</p>
<p class="p4"><br></p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN1024SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN2048SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN4096SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN8192SR44100.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN2048SR48000.wav</p>
<p class="p6"><span class="s1"><span class="Apple-converted-space"> </span></span>QspeckernN4096SR48000.wav</p>
<p class="p4"><br></p>
<p class="p5">Only use the one for your output sampling rate. Bigger N means more stability and resolution but longer delay and higher average CPU cost. N= 2048 is a good tradeoff if you don't want to track over 1000Hz fundamentals. The 48000 SR files are untested and provided without any promises.<span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5"><b>in</b>- the audio rate input signal</p>
<p class="p5"><b>databufnum</b>- you must provide the initialisation data required by Qitch. This in the form of a .wav file that must be loaded to a buffer (see examples below).<span class="Apple-converted-space">  </span>The data files should have come with this UGen.<span class="Apple-converted-space"> </span></p>
<p class="p5"><b>ampThreshold</b>- Qitch outputs a 0 in hasFreq if the input amplitude is below this threshold. Same as original Pitch.<span class="Apple-converted-space"> </span></p>
<p class="p5"><b>algoflag</b>- 0 means use just the constant Q template pattern matcher. 1 flags the refinement based on the phase estimate.</p>
<p class="p5"><b>ampbufnum</b>- you may provide an 11 component buffer with template amplitudes- see example below.<span class="Apple-converted-space"> </span></p>
<p class="p5"><b>minfreq</b>- minimum output frequency in Hz</p>
<p class="p5"><b>maxfreq</b>- maximum output frequency in Hz</p>
<p class="p4"><br></p>
<p class="p5">In technical terms, this UGen calculates an FFT, applying Brown and Puckette's efficient constant Q transform on a quartertone scale, base note F3= 174.6Hz. Cross correlation search leads to the best match for a harmonic spectrum grid with falling amplitude components. A further fine tuning takes place based on instantaneous frequency estimation (rate of change of phase) for the winning FFT bin.<span class="Apple-converted-space"> </span></p>
<p class="p4"><br></p>
<p class="p5">The algorithms are based on the following papers:</p>
<p class="p4"><span class="Apple-converted-space"> </span></p>
<p class="p5">Judith C. Brown and Miller S. Puckette, 1992, An efficient algorithm for the calculation of a constant Q transform. Journal of the Acoustical Society of America. 92(5); 2698-701.</p>
<p class="p4"><span class="Apple-converted-space">   </span></p>
<p class="p5">Judith C. Brown, 1992, Musical Fundamental Frequency Tracking Using a Pattern Recognition Method. Journal of the Acoustical Society of America. 92(3); 1394-402.</p>
<p class="p4"><span class="Apple-converted-space">   </span></p>
<p class="p5">Judith C. Brown and Miller S. Puckette, 1993, A High-Resolution Fundamental Frequency Determination Based on Phase Changes of the Fourier Transform. Journal of the Acoustical Society of America. 94(2); 662-7.</p>
<p class="p4"><span class="Apple-converted-space">         </span></p>
<p class="p4"><br></p>
<p class="p5"><b>Examples: (use headphones!)</b></p>
<p class="p4"><br></p>
<p class="p7">s = <span class="s2">Server</span>.local;</p>
<p class="p8"><br></p>
<p class="p9">//assumes data file is in SC home application directory; else provide full path</p>
<p class="p10"><span class="s3">b = </span><span class="s4">Buffer</span><span class="s3">.read(s, </span>"QspeckernN4096SR44100.wav"<span class="s3">);<span class="Apple-converted-space"> </span></span></p>
<p class="p11">//this line is absolutely essential! You must load the data required by the UGen!<span class="Apple-converted-space"> </span></p>
<p class="p12"><br></p>
<p class="p9"><span class="s3">b.numFrames </span>//it's not that much data</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p7">(</p>
<p class="p7">a= <span class="s2">SynthDef</span>(<span class="s5">"testqitch"</span>,{<span class="s2">arg</span> infreq=440;</p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">var</span> in, freq, hasFreq, out;</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span>in=<span class="s2">SinOsc</span>.ar(infreq);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Qitch</span>.kr(in, b.bufnum,0.01,1);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0,[<span class="s2">SinOsc</span>.ar(freq,0.1),in]);</p>
<p class="p7">}).play(s);</p>
<p class="p7">)</p>
<p class="p8"><br></p>
<p class="p7">a.set(<span class="s6">\infreq</span>,237);</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p13"><span class="s3">c=</span><span class="s2">Buffer</span><span class="s3">.read(s,</span><span class="s5">"/Volumes/data/audio/nikkisitar/warmup.wav"</span><span class="s3">); </span>//sitar test file, try anything you have on your disk</p>
<p class="p8"><br></p>
<p class="p7">c.numFrames</p>
<p class="p8"><br></p>
<p class="p13"><span class="s3">( </span>//sample tracking</p>
<p class="p6"><span class="s2">SynthDef</span><span class="s3">(</span>"pitchFollow1"<span class="s3">,{</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">var</span> in, amp, freq, hasFreq, out;</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span>in = <span class="s2">PlayBuf</span>.ar(1,c.bufnum, loop:1);</p>
<p class="p7"><span class="Apple-tab-span">	</span>amp = <span class="s2">Amplitude</span>.kr(in, 0.05, 0.05);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Qitch</span>.kr(in, b.bufnum, 0.1,1, -1,261, 800 );</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span>out = <span class="s2">Mix</span>.new(<span class="s2">VarSaw</span>.ar(freq * [0.5,1,2], 0, <span class="s2">LFNoise1</span>.kr(0.3,0.1,0.1), amp));</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0,[out,in])</p>
<p class="p7">}).play(s);</p>
<p class="p7">)</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p14"><span class="s3">b = </span><span class="s2">Buffer</span><span class="s3">.read(s, </span><span class="s5">"QspeckernN2048SR44100.wav"</span><span class="s3">); </span>//quicker response with this data set</p>
<p class="p8"><br></p>
<p class="p13"><span class="s3">d = </span><span class="s2">Buffer</span><span class="s3">.alloc(s,11); </span>//make an amp template</p>
<p class="p15">d.setn(0, [1,0.98,0.92,0.88,0.84,0.8,0.76,0.72,1.68,1.64,1.6]); <span class="s7">//must have 11 components</span></p>
<p class="p8"><br></p>
<p class="p13">//analogous to example in the Pitch helpfile<span class="Apple-converted-space"> </span></p>
<p class="p7">(</p>
<p class="p6"><span class="s2">SynthDef</span><span class="s3">(</span>"pitchFollow1"<span class="s3">,{</span></p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">var</span> in, amp, freq, hasFreq, out;</p>
<p class="p7"><span class="Apple-tab-span">	</span>in = <span class="s2">Mix</span>.new(<span class="s2">AudioIn</span>.ar([1,2]));</p>
<p class="p7"><span class="Apple-tab-span">	</span>amp = <span class="s2">Amplitude</span>.kr(in, 0.05, 0.05);</p>
<p class="p7"><span class="Apple-tab-span">	</span># freq, hasFreq = <span class="s2">Qitch</span>.kr(in, b.bufnum, 0.02, 1, d.bufnum, 160, 880);</p>
<p class="p8"><span class="Apple-tab-span">	</span></p>
<p class="p13"><span class="s3"><span class="Apple-tab-span">	</span></span>//freq = Lag.kr(freq.cpsmidi.round(1).midicps, 0.05);</p>
<p class="p7"><span class="Apple-tab-span">	</span>out = <span class="s2">Mix</span>.new(<span class="s2">VarSaw</span>.ar(freq * [0.5,1,2], 0, <span class="s2">LFNoise1</span>.kr(0.3,0.1,0.1), amp));</p>
<p class="p7"><span class="Apple-tab-span">	</span>6.do({</p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>out = <span class="s2">AllpassN</span>.ar(out, 0.040, [0.040.rand,0.040.rand], 2)</p>
<p class="p7"><span class="Apple-tab-span">	</span>});</p>
<p class="p7"><span class="Apple-tab-span">	</span><span class="s2">Out</span>.ar(0,out)</p>
<p class="p7">}).play(s);</p>
<p class="p7">)</p>
<p class="p8"><br></p>
<p class="p8"><br></p>
<p class="p4"><br></p>
<p class="p4"><br></p>
</body>
</html>
